package com.sjsu.aws.simplocks;

import java.util.HashMap;
import java.util.Map;

/**
 * 
 * @author Shweta Dattatreya
 * 
 */
public class SimpleLock implements LockService {

	private AWSClient client;
	private String id;
	private long timeout;
	private LockListener listener = null;
	private LockWatcher watcher;

	private class LockWatcherImpl implements LockWatcher {
		LockService ls;

		LockWatcherImpl(LockService l) {
			ls = l;
		}

		public void stateChanged() {
			try {
				ls.lock();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 
	 * @throws Exception
	 */
	public SimpleLock() throws Exception {
		client = AWSClient.getInstance();
		id = NodeId.getId();
		timeout = 10 * 1000; // 10s
		watcher = new LockWatcherImpl(this);
		synchronized (client) {
			client.addWatcher(watcher);
		}
	}

	/**
	 * 
	 * @return
	 */
	String getExpiryTS() {
		return String.valueOf(System.currentTimeMillis() + timeout);
	}

	/**
	 * 
	 * @param l
	 */
	public void setLockListener(LockListener l) {
		listener = l;
	}

	@Override
	public void lock() throws Exception {
		synchronized (client) {
			if (client.queryTable().size() == 0) {
				client.insertItem(id, getExpiryTS());
				if (listener != null) {
					listener.lockAcquired();
				}
			}
		}
	}

	@Override
	public void unlock() throws Exception {
		synchronized (client) {
			Map<String, String> result = new HashMap<String, String>();
			result = client.queryTable();
			assert (result.size() > 0 && result.containsKey(id));
			if (listener != null) {
				listener.lockReleased();
			}
			client.removeWatcher(watcher);
			client.deleteItem(id);
		}
	}
}